package com.jweb.util;

import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpServletRequestUtil {
	private static Logger logger = LoggerFactory.getLogger(HttpServletRequestUtil.class);

	public static String getHostByReferrer(String referrer) {
		URL url = null;
		try {
			url = new URL(referrer);
		} catch (Exception e) {
			logger.error("获取请求url对应域名出错");
		}
		return url.getHost();
	}

	public static String getAppHost(HttpServletRequest request) {
		StringBuffer url = request.getRequestURL();
		return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
	}

	public static String getAppHostWithContext(HttpServletRequest request) {
		return getAppHost(request) + request.getServletContext().getContextPath();
	}

	/**
	 * 根据http请求模拟构建一个get样式的url
	 * 
	 * @param request
	 * @return
	 */
	public static String buildRequestUrl(HttpServletRequest request) {
		StringBuffer originalURL = request.getRequestURL();
		String url = originalURL.toString();
		Map<String, String[]> parameters = request.getParameterMap();
		if (parameters != null && parameters.size() > 0) {
			originalURL.append("?");
			for (String key : parameters.keySet()) {
				String[] values = parameters.get(key);
				for (int i = 0; i < values.length; i++) {
					originalURL.append(key).append("=").append(values[i]).append("&");
				}
			}
			url = originalURL.substring(0, originalURL.length() - 1); // 去掉最后一个&
		}
		return url;
	}

	/**
	 * 打印出请求的详细信息
	 * 
	 * @param request
	 * @throws IOException
	 */
	public static void logRequestDetail(HttpServletRequest request) {
		logger.debug("请求的详细属性为：");
		logger.debug("参数: ");
		// 参数
		Map<String, String[]> parameters = request.getParameterMap();
		if (parameters != null && parameters.size() > 0) {
			for (String key : parameters.keySet()) {
				String[] values = parameters.get(key);
				for (int i = 0; i < values.length; i++) {
					logger.debug("param: [" + key + "] " + values[i]);
				}
			}
		}
		logger.debug("其它: ");
		logger.debug("Protocol: " + request.getProtocol());
		logger.debug("Scheme: " + request.getScheme());
		logger.debug("Server Name: " + request.getServerName());
		logger.debug("Server Port: " + request.getServerPort());
		logger.debug("Server Info: " + request.getServletContext().getServerInfo());
		logger.debug("Remote Addr: " + request.getRemoteAddr());
		logger.debug("Remote Host: " + request.getRemoteHost());
		logger.debug("Remote User" + request.getRemoteUser());
		logger.debug("Character Encoding: " + request.getCharacterEncoding());
		logger.debug("Content Length: " + request.getContentLength());
		logger.debug("Content Type: " + request.getContentType());
		logger.debug("Auth Type: " + request.getAuthType());
		logger.debug("HTTP Method: " + request.getMethod());
		logger.debug("Path Info: " + request.getPathInfo());
		logger.debug("Path Trans: " + request.getPathTranslated());
		logger.debug("Query String: " + request.getQueryString());
		logger.debug("Session Id: " + request.getRequestedSessionId());
		logger.debug("Request URI: " + request.getRequestURI());
		logger.debug("Servlet Path: " + request.getServletPath());
		logger.debug("Accept: " + request.getHeader("Accept"));
		logger.debug("Host: " + request.getHeader("Host"));
		logger.debug("Referer : " + request.getHeader("Referer"));
		logger.debug("Accept-Language : " + request.getHeader("Accept-Language"));
		logger.debug("Accept-Encoding : " + request.getHeader("Accept-Encoding"));
		logger.debug("User-Agent : " + request.getHeader("User-Agent"));
		logger.debug("Connection : " + request.getHeader("Connection"));
		logger.debug("Cookie : " + request.getHeader("Cookie"));
		logger.debug("Session Created : " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(request.getSession().getCreationTime())));
		logger.debug("Session LastAccessed : "
				+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(request.getSession().getLastAccessedTime())));
	}

	public static void logMyRequestDetail(HttpServletRequest request) {
		StringBuffer sb = new StringBuffer(64);
		Map<String, String[]> parameters = request.getParameterMap();
		if (parameters != null && parameters.size() > 0) {
			for (String key : parameters.keySet()) {
				String[] values = parameters.get(key);
				for (int i = 0; i < values.length; i++) {
					sb.append(key + "=" + values[i] + ";");
				}
			}
			logger.info("Params :" + sb.toString());
		}
		logger.info("Request URI : " + request.getRequestURI());
		logger.info("IP : " + getIp(request));
	}

	/**
	 * 
	 * @param request
	 * @return 请求IP地址
	 */
	public static String getIp(HttpServletRequest request) {
		//
		String ip = null;
		//
		ip = request.getHeader("X-Forwarded-For");
		if (isRealIP(ip)) {
			return getRealIp(ip);
		}
		//
		ip = request.getHeader("Proxy-Client-IP");
		if (isRealIP(ip)) {
			return getRealIp(ip);
		}
		//
		ip = request.getHeader("WL-Proxy-Client-IP");
		if (isRealIP(ip)) {
			return getRealIp(ip);
		}
		//
		ip = request.getHeader("HTTP_CLIENT_IP");
		if (isRealIP(ip)) {
			return getRealIp(ip);
		}
		//
		ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		if (isRealIP(ip)) {
			return getRealIp(ip);
		}
		//
		ip = request.getParameter("__fromReferIP");
		if (isRealIP(ip)) {
			return getRealIp(ip);
		}
		// NGINX用
		ip = request.getHeader("X-Real-IP");
		if (isRealIP(ip)) {
			return getRealIp(ip);
		}
		ip = request.getRemoteAddr();
		//
		return ip;
	}

	/**
	 * @param ip
	 * @return
	 */
	private static boolean isRealIP(String ip) {
		return !FormatUtil.isEmpty(ip) && !"unknown".equalsIgnoreCase(ip);
	}

	/**
	 * @param ip
	 * @return
	 */
	private static String getRealIp(String ip) {
		if (String.valueOf(ip).indexOf(",") != -1) {
			return FormatUtil.getLeft(ip.split(",")[0], 15);
		}
		return ip;
	}

	/**
	 * 得到HttpServletRequest的参数map
	 */
	public static Map<String, String> getParameterMap(HttpServletRequest request) {
		Map<String, String[]> properties = request.getParameterMap();
		// 返回值Map
		Map<String, String> returnMap = new HashMap<String, String>();
		String name;
		String value = "";
		for (Entry<String, String[]> entry : properties.entrySet()) {
			name = (String) entry.getKey();
			String[] values = entry.getValue();
			if (values == null) {
				value = "";
			} else {
				for (int i = 0; i < values.length; i++) {
					value = values[i] + ",";
				}
				value = value.substring(0, value.length() - 1);
			}
			returnMap.put(name, value);
		}
		return returnMap;
	}

	/**
	 * @return 本机IP
	 * @throws SocketException
	 */
	public static String getLocalRealIp() throws SocketException {
		String localip = null;// 本地IP，如果没有配置外网IP则返回它
		String netip = null;// 外网IP
		String localHost = null;
		try {
			localHost = InetAddress.getLocalHost().getHostAddress().toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
		InetAddress ip = null;
		boolean finded = false;// 是否找到外网IP

		while (netInterfaces.hasMoreElements() && !finded) {
			NetworkInterface ni = netInterfaces.nextElement();
			Enumeration<InetAddress> address = ni.getInetAddresses();
			while (address.hasMoreElements()) {
				ip = address.nextElement();
				if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 外网IP
					netip = ip.getHostAddress();
					finded = true;
					break;
				} else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 内网IP
					localip = ip.getHostAddress();
					if (localip.equals(localHost)) {
						finded = true;
						break;
					}
				}
			}
		}
		if (netip != null && !"".equals(netip)) {
			return netip;
		} else {
			return localip;
		}
	}

	/**
	 * 不区分参数大小写，获取参数对应的值
	 * 
	 * @param request
	 * @param parameter
	 * @return
	 */
	public static String getRequestIgnoreCaseParameter(HttpServletRequest request, String parameter) {
		String paramValue = null;
		Enumeration<String> pnameEnum = request.getParameterNames();
		while (pnameEnum.hasMoreElements()) {
			String paramName = pnameEnum.nextElement();
			if (paramName.equalsIgnoreCase(parameter)) {
				paramValue = request.getParameter(paramName);
				break;
			}
		}
		return paramValue;
	}

	public static void ckremort(String userAgent) {
		Pattern pattern = Pattern.compile(";\\s?(\\S*?\\s?\\S*?)\\s?(Build)?/");
		Matcher matcher = pattern.matcher(userAgent);
		String model = null;
		if (matcher.find()) {
			model = matcher.group(1).trim();
			logger.info("通过userAgent解析出机型：" + model);
		}
	}

	public static void main(String[] args) throws SocketException {
		System.out.println(getLocalRealIp());
		ckremort("Huawei U8800    Android 2.3.3   QQ 3.7  MQQBrowser/3.7/Adr (Linux; U; 2.3.5; zh-cn; U8800 Build/U8800V100R001C00B528G002;480*800)   Speed Mode  有用(0)  ");
	}
}
